x11: Handle case where clipboard was reclaimed quickly
authorBenjamin Otte <otte@redhat.com>
Fri, 1 Dec 2017 06:42:36 +0000 (07:42 +0100)
committerBenjamin Otte <otte@redhat.com>
Sun, 3 Dec 2017 04:46:49 +0000 (05:46 +0100)
When the reply to a TARGETS request comes in, the clipboard may already
be reclaimed by the local app. Deal with that case (in an ugly way,
strictly speaking we should use a cancellable here).

This happens for example at startup when the initial TARGETS requests
have not been answered until after the main widow popped up. And if such
a window immediately claims the primary clipboard (like when the initial
focus is inside an entry), this race will happen.

gdk/x11/gdkclipboard-x11.c

index 8037912f253ce38ce6ead182ad1f08a0b8f090aa..4864c1f8bba925584fb1b2fa7f924e850105850a 100644 (file)
@@ -408,6 +408,15 @@ gdk_x11_clipboard_request_targets_finish (GObject      *source_object,
       g_object_unref (cb);
       return;
     }
+  else if (gdk_clipboard_is_local (GDK_CLIPBOARD (cb)))
+    {
+      /* FIXME: Use a cancellable for this request, so that we don't do he brittle
+       * is_local() check */
+      g_bytes_unref (bytes);
+      g_object_unref (stream);
+      g_object_unref (cb);
+      return;
+    }
 
   print_atoms (cb,
                "received targets",
@@ -421,8 +430,10 @@ gdk_x11_clipboard_request_targets_finish (GObject      *source_object,
   GDK_NOTE(CLIPBOARD, char *s = gdk_content_formats_to_string (formats); g_printerr ("%s: got formats: %s\n", cb->selection, s); g_free (s));
 
   /* union with previously loaded formats */
+  formats = gdk_content_formats_union (formats, gdk_clipboard_get_formats (GDK_CLIPBOARD (cb)));
   gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb), formats);
   gdk_content_formats_unref (formats);
+  g_bytes_unref (bytes);
 
   g_input_stream_read_bytes_async (stream,
                                    gdk_x11_display_get_max_request_size (display),